package com.github.freegeese.site.shiro;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.Map;

@Slf4j
@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        // URL 拦截器
        Map<String, String> filterChainDefinitionMap = factoryBean.getFilterChainDefinitionMap();
        // 静态资源(匿名访问)
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/403", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        // 退出(退出登录，使用登出过滤器)
        filterChainDefinitionMap.put("/logout", "logout");
        // 认证（剩下都需要进行权限认证）
        filterChainDefinitionMap.put("/**", "authc");

        // 过滤器
        Map<String, Filter> filters = factoryBean.getFilters();
        filters.put("authc", customFormAuthenticationFilter());

        // 登录路径
        factoryBean.setLoginUrl("/login");
        // 登录成功后跳转路径
        factoryBean.setSuccessUrl("/index");
        // 未授权路径
        factoryBean.setUnauthorizedUrl("/unauthorized");

        factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return factoryBean;
    }

    /**
     * 认证、授权数据源
     *
     * @return
     */
    @Bean
    public CustomRealm customRealm() {
        return new CustomRealm();
    }

    /**
     * 自定义表单认证过滤器
     *
     * @return
     */
    @Bean
    public CustomFormAuthenticationFilter customFormAuthenticationFilter() {
        return new CustomFormAuthenticationFilter();
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    /**
     * 安全管理器
     *
     * @return
     */
    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(customRealm());
        return securityManager;
    }

}
